﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GigaSite.Domain.Entities;
using GigaSite.Domain.Interfaces.Repositories;
using GigaSite.Domain.IoC;
using GigaSite.Web.Classes;
using GigaSite.Web.Models.Validators;

namespace GigaSite.Web.Controllers
{
    /// <summary>
    /// Базовый контроллер содержащий общую для всех контроллеров функциональность
    /// </summary>
    public abstract class BaseController : Controller
    {
        #region Common
        
        /// <summary>
        /// Добавляет элемент в цепочку навигации
        /// </summary>
        /// <param name="title">Заголовок элемента</param>
        /// <param name="url">URL для навигации</param>
        /// <param name="active">Элемент активен т.е. по ссылке не переходит</param>
        public void AddNavigationItem(string title, string url, bool active = false)
        {
            if (ViewBag.NavigationChain == null)
            {
                ViewBag.NavigationChain = new List<NavigationChainItem>(); // Коллекция элементов хлебной крошки
            }
            ViewBag.NavigationChain.Add(new NavigationChainItem()
                                            {
                                                Title = title,
                                                Url = url,
                                                Active = active
                                            });
        }

        #endregion

        #region сессии

        /// <summary>
        /// Хранение текущего пользователя
        /// </summary>
        private User _user { get; set; }

        /// <summary>
        /// Текущий авторизованный пользователь
        /// </summary>
        public User CurrentUser
        {
            get
            {
                object fromSess = Session["CurrentUser"];
                if (fromSess == null)
                {
                    return null;
                }
                var userId = (long) fromSess;
                if (_user == null)
                {
                    _user = Locator.GetService<IUsersRepository>().Load(userId);
                }
                return _user;
            }
            set
            {
                Session["CurrentUser"] = value != null ? (object) value.Id : null;
                _user = value;
            }
        }

        /// <summary>
        /// Является ли текущий пользователь авторизованным
        /// </summary>
        public bool IsAuthentificated
        {
            get { return CurrentUser != null; }
        }

        /// <summary>
        /// Авторизирует текущего пользователя
        /// </summary>
        /// <param name="user">Пользователь которого установить как текущего</param>
        /// <param name="remember">Запомнить ли пользователя</param>
        public void AuthorizeUser(User user, bool remember = true)
        {
            CurrentUser = user;
            if (remember)
            {
                // Устанавливаем собственные авторизационные куки
                var authCookie = new HttpCookie("auth");
                authCookie.Values["identity"] = user.Identity;
                authCookie.Values["pass"] = user.Password;
                authCookie.Expires = DateTime.Now.AddDays(365);
                Response.Cookies.Add(authCookie);
            }
        }

        /// <summary>
        /// Убирает авторизацию текущего пользователя и убирает авторизационные куки если они есть
        /// </summary>
        public void CloseAuthorization()
        {
            CurrentUser = null;

            // убираем куки если они есть
            var authCookie = Response.Cookies["auth"];
            if (authCookie != null)
            {
                Response.Cookies.Remove("auth");
            }
        }

        /// <summary>
        /// Возвращает вид содержащий указанные ошибки валидации
        /// </summary>
        /// <param name="viewName">Имя вью</param>
        /// <param name="errors">Коллекция ошибок</param>
        /// <param name="model">Модель данных</param>
        /// <returns>Вид с ошибками валидации</returns>
        public ActionResult ViewWithModelErrors(string viewName, IList<ModelValidationError> errors, object model)
        {
            foreach (var modelValidationError in errors)
            {
                ModelState.AddModelError(modelValidationError.FieldName,modelValidationError.Message);
            }
            return View(viewName, model);
        }

        #endregion

        #region Работа с JSON

        /// <summary>
        /// Отдает успешный результат выполнения операции в Json формате
        /// </summary>
        /// <returns></returns>
        public JsonResult JsonSuccess()
        {
            return Json(new {success = true});
        }

        /// <summary>
        /// Отдает неуспешный результат выполнения операции в Json формате с указанным сообщением
        /// </summary>
        /// <param name="message">сообщение</param>
        /// <returns></returns>
        public JsonResult JsonError(string message)
        {
            Response.StatusCode = 500;
            return Json(new {success = false, msg = message});
        }

        #endregion

        #region Работа с изображениями

        /// <summary>
        /// Получает путь к уменьшенной копии изображения
        /// </summary>
        /// <param name="imageUri">Путь в системе хранения файлов</param>
        /// <param name="height">Высота</param>
        /// <param name="imagesRepository">Репозиторий изображений</param>
        /// <param name="width">Ширина</param>
        /// <returns></returns>
        protected string GetThumbImageUrl(string imageUri, int width, int height, IImagesRepository imagesRepository = null)
        {
            // Репозиторий
            if (imagesRepository == null)
                imagesRepository = Locator.GetService<IImagesRepository>();

            // Загружаем картинку
            var image = imagesRepository.GetImage(imageUri);
            if (image == null)
            {
                return String.Empty;
            }

            // Формируем URL
            return Url.Action("Thumb", "Images", new {area = "", id = image.Id, width, height});
        }

        #endregion
    }
}
